package com.huqi.limiting;

import com.huqi.log.LoggerUtil;
import com.huqi.thread.ScheduledExecutorUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 胡琦
 * @date 2021-07-29 星期四 23:00
 */
public class TokenBucket {
    private final static Logger LOGGER = LoggerFactory.getLogger(TokenBucket.class);

    private static final String KEY = "KEY";

    /**
     * 最大存放300个令牌
     */
    private static final int SIZE = 3;
    private final static List<String> BUCKET = new ArrayList<>(SIZE);

    static {
        setAndStartRefresh();
        for (int i = 0; i < SIZE; i++) {
            BUCKET.add(KEY);
        }
    }

    private static void setAndStartRefresh() {
        // LoggerUtil.info(LOGGER, "token 定时任务正在执行!!!!!" );
        ScheduledExecutorUtil.getExecutorService().scheduleAtFixedRate(TokenBucket::setToken, 1, 1000, TimeUnit.MILLISECONDS);
    }

    public static void init() {
        LoggerUtil.info(LOGGER, "TokenBucket init success");
    }

    /**
     * 放令牌
     */
    private static void setToken() {
        if (BUCKET.size() < SIZE) {
            BUCKET.add(KEY + System.currentTimeMillis() + UUID.randomUUID());
            LoggerUtil.info(LOGGER, "放了个令牌");
        }
    }

    /**
     * 尝试获取令牌
     * @return
     */
    public static boolean getToken() {
        String remove = null;
        Lock lock = new ReentrantLock();
        lock.lock();
        try {
            remove = BUCKET.remove(BUCKET.size()-1);
        }catch (Exception e) {
            LoggerUtil.error(e, LOGGER, "获取令牌失败..");
        }finally {
            lock.unlock();
        }
        return StringUtils.isNotBlank(remove);
        // return false;
    }

}
